Interactive map of traffic accidents in the metropolitan region of São Paulo, clustered by region and type, during the year 2015.
Appendix I - Source Code
Made with R and Leaflet, source code:
# load libraries
# install.packages("leaflet")
# install.packages("dplyr")
suppressPackageStartupMessages(library(leaflet))
suppressPackageStartupMessages(library(stringr))
suppressPackageStartupMessages(library(dplyr))
#load and clean
data2015 <- read.csv("./dados/2015/ocorrencias-transito-pmsp-2015.csv")
data2015$lng <- as.numeric(str_match(data2015$WKT, ".*\\((.*)\\s(.*)\\)")[,2])
data2015$lat <- as.numeric(str_match(data2015$WKT, ".*\\((.*)\\s(.*)\\)")[,3])
data2015 <- data2015[complete.cases(data2015[,c("lat","lng")]),]
# add legenda com o TIPO_ACIDE
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="CO"] <- "Colisão"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="CF"] <- "Colisão frontal"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="CT"] <- "Colisão traseira"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="CL"] <- "Colisão lateral"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="CV"] <- "Colisão Transversa"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="CP"] <- "Capotamento"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="TB"] <- "Tombamento"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="AT"] <- "Atropelamento"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="AA"] <- "Atropelamento animal"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="CH"] <- "Choque"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="QM"] <- "Queda moto/bicicleta"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="QV"] <- "Queda veículo"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="QD"] <- "Queda ocupante dentro"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="QF"] <- "Queda ocupante fora"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="OU"] <- "Outros"
data2015$TIPO_ACIDE_DESCR[data2015$TIPO_ACIDE=="SI"] <- "Sem informação"
# normaliza numero de vitimas
data2015$VITIMAS_NORM[data2015$VITIMAS < 100] <- data2015[data2015$VITIMAS < 100,17]
data2015$VITIMAS_NORM[data2015$VITIMAS >= 100] <- data2015[data2015$VITIMAS >= 100,17] %/% 100
data2015$VITIMAS_MORTE <- 0
data2015$VITIMAS_MORTE[data2015$VITIMAS >= 100] <- data2015[data2015$VITIMAS >= 100,17] %% 100
# popup
data2015$popup <- paste(data2015$TIPO_ACIDE_DESCR, "<br><br>vitimas feridas:", data2015$VITIMAS_NORM, "<br>vitimas fatais:", data2015$VITIMAS_MORTE, "<br>cod. localização: ", data2015$CADLOGA);
# color
data2015$color[data2015$COD_ACID==2] <- "blue"
data2015$color[data2015$COD_ACID==4] <- "red"
# top 10 locations
locations <- data2015 %>%
group_by(WKT) %>%
summarize(n=n(), vitimas=sum(VITIMAS_NORM), vitimas_morte=sum(VITIMAS_MORTE))
locations$lng <- as.numeric(str_match(locations$WKT, ".*\\((.*)\\s(.*)\\)")[,2])
locations$lat <- as.numeric(str_match(locations$WKT, ".*\\((.*)\\s(.*)\\)")[,3])
locations <- arrange(locations, desc(n))
top10 <- head(locations, 10)
top10$popup <- paste("<b>TOP 10 in number of accidents</b><br><br>total accidents: ", top10$n, "<br>victims: ", top10$vitimas, "<br>deaths: ", top10$vitimas_morte)
locations <- arrange(locations, desc(vitimas_morte))
deadly <- head(locations, 10)
deadly$popup <- paste("<b>Deadly Location</b><br><br>total accidents: ", deadly$n, "<br>victims: ", deadly$vitimas, "<br>deaths: ", deadly$vitimas_morte)
# most run over
run_over <- data2015[data2015$COD_ACID==4,] %>%
group_by(WKT) %>%
summarize(n=n(), vitimas=sum(VITIMAS_NORM), vitimas_morte=sum(VITIMAS_MORTE))
run_over$lng <- as.numeric(str_match(run_over$WKT, ".*\\((.*)\\s(.*)\\)")[,2])
run_over$lat <- as.numeric(str_match(run_over$WKT, ".*\\((.*)\\s(.*)\\)")[,3])
run_over <- arrange(run_over, desc(n))
run_over <- head(run_over, 5)
run_over$popup <- paste("<b>Top 5 in run over</b><br><br>total accidents: ", run_over$n, "<br>victims: ", run_over$vitimas, "<br>deaths: ", run_over$vitimas_morte)
# cruza dados dos logradouros
logradouros <- read.csv("./dados/logradouros.csv")
# levels(logradouros$classificacao)
logradouros <- logradouros %>%
filter(classificacao == "Transito Rápido", codlog5 != "NULL") %>%
group_by(codlog5) %>%
summarize(n=n())
run_over_rapido <- data2015 %>%
filter(COD_ACID==4, CADLOGA %in% logradouros$codlog5)
# factpal <- colorFactor(topo.colors(17), data2015$TIPO_ACIDE, alpha = FALSE, ordered = TRUE)
data2015 %>% leaflet(width=800, height=500, padding=5) %>% addTiles() %>%
addCircleMarkers(data = data2015, popup=~popup, clusterOptions = markerClusterOptions(), group="all accidents", color=~color, radius = ~VITIMAS_NORM * 4, weight = 3, fillOpacity = ~VITIMAS_MORTE + 0.2 ) %>%
addCircleMarkers(data = run_over_rapido, popup=~popup, group="atropelamentos nas vias expressas", color=~color, radius = 8, weight = 3, fillOpacity = ~VITIMAS_MORTE + 0.2 ) %>%
addCircleMarkers(data = data2015[data2015$COD_ACID==4,], popup=~popup, clusterOptions = markerClusterOptions(), group="somente atropelamentos", color=~color, radius = ~VITIMAS_NORM * 4, weight = 3, fillOpacity = ~VITIMAS_MORTE + 0.2 ) %>%
addMarkers(data=top10, group="worst location", popup=~popup)%>%
addMarkers(data=deadly, group="deadly", popup=~popup)%>%
addMarkers(data=run_over, group="somente atropelamentos", popup=~popup)%>%
addLayersControl(
baseGroups = c("all accidents", "somente atropelamentos", "atropelamentos nas vias expressas"),
overlayGroups = c("worst location", "deadly"),
options = layersControlOptions(collapsed = FALSE),
position="bottomleft"
)
LS0tCnRpdGxlOiAiVHJhZmZpYyBBY2NpZGVudHMgaW4gdGhlIE1ldHJvcG9saXRhbiBSZWdpb24gb2YgU8OjbyBQYXVsbyAtIDIwMTUiCmF1dGhvcjogIldhZ25lciBQaW5oZWlybyIKZGF0ZTogIkphbnVhcnksIDIwMTciCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IHVuaXRlZAogIGh0bWxfbm90ZWJvb2s6CiAgICBmaWdfd2lkdGg6IDE2CiAgICB0aGVtZTogdW5pdGVkCi0tLQoKCkludGVyYWN0aXZlIG1hcCBvZiB0cmFmZmljIGFjY2lkZW50cyBpbiB0aGUgbWV0cm9wb2xpdGFuIHJlZ2lvbiBvZiBTw6NvIFBhdWxvLCBjbHVzdGVyZWQgYnkgcmVnaW9uIGFuZCB0eXBlLCBkdXJpbmcgdGhlIHllYXIgMjAxNS4KClRoYW5rcyB0byB0aGUgcHJvamVjdCBbQ8OzZGlnbyBVcmJhbm9dKGh0dHBzOi8vZ2l0aHViLmNvbS9jb2RpZ291cmJhbm8pIGZvciBtYWtpbmcgcHVibGljIGFjY2VzcyB0byB0aGlzIGRhdGEuCgoKYGBge3IsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMgbG9hZCBsaWJyYXJpZXMKIyBpbnN0YWxsLnBhY2thZ2VzKCJsZWFmbGV0IikKIyBpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KGxlYWZsZXQpKQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShzdHJpbmdyKSkKc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkoZHBseXIpKQoKI2xvYWQgYW5kIGNsZWFuCmRhdGEyMDE1IDwtIHJlYWQuY3N2KCIuL2RhZG9zLzIwMTUvb2NvcnJlbmNpYXMtdHJhbnNpdG8tcG1zcC0yMDE1LmNzdiIpCmRhdGEyMDE1JGxuZyA8LSBhcy5udW1lcmljKHN0cl9tYXRjaChkYXRhMjAxNSRXS1QsICIuKlxcKCguKilcXHMoLiopXFwpIilbLDJdKQpkYXRhMjAxNSRsYXQgPC0gYXMubnVtZXJpYyhzdHJfbWF0Y2goZGF0YTIwMTUkV0tULCAiLipcXCgoLiopXFxzKC4qKVxcKSIpWywzXSkKZGF0YTIwMTUgPC0gZGF0YTIwMTVbY29tcGxldGUuY2FzZXMoZGF0YTIwMTVbLGMoImxhdCIsImxuZyIpXSksXQoKIyBhZGQgbGVnZW5kYSBjb20gbyBUSVBPX0FDSURFCmRhdGEyMDE1JFRJUE9fQUNJREVfREVTQ1JbZGF0YTIwMTUkVElQT19BQ0lERT09IkNPIl0gPC0gIkNvbGxpc2lvbiAvIENvbGlzw6NvIgpkYXRhMjAxNSRUSVBPX0FDSURFX0RFU0NSW2RhdGEyMDE1JFRJUE9fQUNJREU9PSJDRiJdIDwtICJGcm9udGFsIGNvbGxpc2lvbiAvIENvbGlzw6NvIGZyb250YWwiCmRhdGEyMDE1JFRJUE9fQUNJREVfREVTQ1JbZGF0YTIwMTUkVElQT19BQ0lERT09IkNUIl0gPC0gIlJlYXIgY29sbGlzaW9uIC8gQ29saXPDo28gdHJhc2VpcmEiCmRhdGEyMDE1JFRJUE9fQUNJREVfREVTQ1JbZGF0YTIwMTUkVElQT19BQ0lERT09IkNMIl0gPC0gIlNpZGUgY29sbGlzaW9uIC8gQ29saXPDo28gbGF0ZXJhbCIKZGF0YTIwMTUkVElQT19BQ0lERV9ERVNDUltkYXRhMjAxNSRUSVBPX0FDSURFPT0iQ1YiXSA8LSAiVHJhbnN2ZXJzZSBDb2xsaXNpb24gLyBDb2xpc8OjbyBUcmFuc3ZlcnNhIgpkYXRhMjAxNSRUSVBPX0FDSURFX0RFU0NSW2RhdGEyMDE1JFRJUE9fQUNJREU9PSJDUCJdIDwtICJSb2xsb3ZlciAvIENhcG90YW1lbnRvIgpkYXRhMjAxNSRUSVBPX0FDSURFX0RFU0NSW2RhdGEyMDE1JFRJUE9fQUNJREU9PSJUQiJdIDwtICJPdmVydHVybmluZyAvIFRvbWJhbWVudG8iCmRhdGEyMDE1JFRJUE9fQUNJREVfREVTQ1JbZGF0YTIwMTUkVElQT19BQ0lERT09IkFUIl0gPC0gIlJ1biBvdmVyIGJ5IHZlaGljbGUgLyBBdHJvcGVsYW1lbnRvIgpkYXRhMjAxNSRUSVBPX0FDSURFX0RFU0NSW2RhdGEyMDE1JFRJUE9fQUNJREU9PSJBQSJdIDwtICJBdHJvcGVsYW1lbnRvIGFuaW1hbCIKZGF0YTIwMTUkVElQT19BQ0lERV9ERVNDUltkYXRhMjAxNSRUSVBPX0FDSURFPT0iQ0giXSA8LSAiU2hvY2sgLyBDaG9xdWUiCmRhdGEyMDE1JFRJUE9fQUNJREVfREVTQ1JbZGF0YTIwMTUkVElQT19BQ0lERT09IlFNIl0gPC0gIkZhbGwgYmlrZXxiaWN5Y2xlIC8gUXVlZGEgbW90b3xiaWNpY2xldGEiCmRhdGEyMDE1JFRJUE9fQUNJREVfREVTQ1JbZGF0YTIwMTUkVElQT19BQ0lERT09IlFWIl0gPC0gIlZlaGljbGUgZmFsbCAvIFF1ZWRhIHZlw61jdWxvIgpkYXRhMjAxNSRUSVBPX0FDSURFX0RFU0NSW2RhdGEyMDE1JFRJUE9fQUNJREU9PSJRRCJdIDwtICJGYWxsaW5nIC0gT2NjdXBhbnQgaW5zaWRlIC8gUXVlZGEgb2N1cGFudGUgZGVudHJvIgpkYXRhMjAxNSRUSVBPX0FDSURFX0RFU0NSW2RhdGEyMDE1JFRJUE9fQUNJREU9PSJRRiJdIDwtICJGYWxsaW5nIC0gT2NjdXBhbnQgb3V0c2lkZSAvIFF1ZWRhIG9jdXBhbnRlIGZvcmEiCmRhdGEyMDE1JFRJUE9fQUNJREVfREVTQ1JbZGF0YTIwMTUkVElQT19BQ0lERT09Ik9VIl0gPC0gIk90aGVyIC8gT3V0cm9zIgpkYXRhMjAxNSRUSVBPX0FDSURFX0RFU0NSW2RhdGEyMDE1JFRJUE9fQUNJREU9PSJTSSJdIDwtICJObyBJbmZvcm1hdGlvbiAvIFNlbSBpbmZvcm1hw6fDo28iCgojIG5vcm1hbGl6YSBudW1lcm8gZGUgdml0aW1hcwpkYXRhMjAxNSRWSVRJTUFTX05PUk1bZGF0YTIwMTUkVklUSU1BUyA8IDEwMF0gPC0gZGF0YTIwMTVbZGF0YTIwMTUkVklUSU1BUyA8IDEwMCwxN10KZGF0YTIwMTUkVklUSU1BU19OT1JNW2RhdGEyMDE1JFZJVElNQVMgPj0gMTAwXSA8LSBkYXRhMjAxNVtkYXRhMjAxNSRWSVRJTUFTID49IDEwMCwxN10gJS8lIDEwMApkYXRhMjAxNSRWSVRJTUFTX01PUlRFIDwtIDAKZGF0YTIwMTUkVklUSU1BU19NT1JURVtkYXRhMjAxNSRWSVRJTUFTID49IDEwMF0gPC0gZGF0YTIwMTVbZGF0YTIwMTUkVklUSU1BUyA+PSAxMDAsMTddICUlIDEwMAoKIyBwb3B1cApkYXRhMjAxNSRwb3B1cCA8LSBwYXN0ZShkYXRhMjAxNSRUSVBPX0FDSURFX0RFU0NSLCAiPGJyPjxicj52aWN0aW1zOiIsIGRhdGEyMDE1JFZJVElNQVNfTk9STSwgIjxicj5kZWF0aHM6IiwgZGF0YTIwMTUkVklUSU1BU19NT1JURSwgIjxicj5kYXRlOiAiLCBkYXRhMjAxNSREQVRBLCAiPGJyPmxvY2F0aW9uIGNvZGU6ICIsIGRhdGEyMDE1JENBRExPR0EpOwoKIyBjb2xvcgpkYXRhMjAxNSRjb2xvcltkYXRhMjAxNSRDT0RfQUNJRD09Ml0gPC0gImJsdWUiCmRhdGEyMDE1JGNvbG9yW2RhdGEyMDE1JENPRF9BQ0lEPT00XSA8LSAicmVkIiAKCiMgdG9wIDEwIGxvY2F0aW9ucwpsb2NhdGlvbnMgPC0gZGF0YTIwMTUgJT4lCiAgZ3JvdXBfYnkoV0tUKSAlPiUKICBzdW1tYXJpemUobj1uKCksIHZpdGltYXM9c3VtKFZJVElNQVNfTk9STSksIHZpdGltYXNfbW9ydGU9c3VtKFZJVElNQVNfTU9SVEUpKQoKbG9jYXRpb25zJGxuZyA8LSBhcy5udW1lcmljKHN0cl9tYXRjaChsb2NhdGlvbnMkV0tULCAiLipcXCgoLiopXFxzKC4qKVxcKSIpWywyXSkKbG9jYXRpb25zJGxhdCA8LSBhcy5udW1lcmljKHN0cl9tYXRjaChsb2NhdGlvbnMkV0tULCAiLipcXCgoLiopXFxzKC4qKVxcKSIpWywzXSkKIyBsb2NhdGlvbnMkbG5nMSA8LSBsb2NhdGlvbnMkbG5nIC0gMC4wMDEKIyBsb2NhdGlvbnMkbGF0MSA8LSBsb2NhdGlvbnMkbGF0IC0gMC4wMDEKIyBsb2NhdGlvbnMkbG5nMiA8LSBsb2NhdGlvbnMkbG5nICsgMC4wMDEKIyBsb2NhdGlvbnMkbGF0MiA8LSBsb2NhdGlvbnMkbGF0ICsgMC4wMDEKCmxvY2F0aW9ucyA8LSBhcnJhbmdlKGxvY2F0aW9ucywgZGVzYyhuKSkKCnRvcDEwIDwtIGhlYWQobG9jYXRpb25zLCAxMCkKCnRvcDEwJHBvcHVwIDwtIHBhc3RlKCI8Yj5UT1AgMTAgaW4gbnVtYmVyIG9mIGFjY2lkZW50czwvYj48YnI+PGJyPnRvdGFsIGFjY2lkZW50czogIiwgdG9wMTAkbiwgIjxicj52aWN0aW1zOiAiLCB0b3AxMCR2aXRpbWFzLCAiPGJyPmRlYXRoczogIiwgdG9wMTAkdml0aW1hc19tb3J0ZSkKCmxvY2F0aW9ucyA8LSBhcnJhbmdlKGxvY2F0aW9ucywgZGVzYyh2aXRpbWFzX21vcnRlKSkKZGVhZGx5IDwtIGhlYWQobG9jYXRpb25zLCAxMCkKZGVhZGx5JHBvcHVwIDwtIHBhc3RlKCI8Yj5EZWFkbHkgTG9jYXRpb248L2I+PGJyPjxicj50b3RhbCBhY2NpZGVudHM6ICIsIGRlYWRseSRuLCAiPGJyPnZpY3RpbXM6ICIsIGRlYWRseSR2aXRpbWFzLCAiPGJyPmRlYXRoczogIiwgZGVhZGx5JHZpdGltYXNfbW9ydGUpCgojIG1vc3QgcnVuIG92ZXIKcnVuX292ZXIgPC0gZGF0YTIwMTVbZGF0YTIwMTUkQ09EX0FDSUQ9PTQsXSAlPiUKICBncm91cF9ieShXS1QpICU+JQogIHN1bW1hcml6ZShuPW4oKSwgdml0aW1hcz1zdW0oVklUSU1BU19OT1JNKSwgdml0aW1hc19tb3J0ZT1zdW0oVklUSU1BU19NT1JURSkpCgpydW5fb3ZlciRsbmcgPC0gYXMubnVtZXJpYyhzdHJfbWF0Y2gocnVuX292ZXIkV0tULCAiLipcXCgoLiopXFxzKC4qKVxcKSIpWywyXSkKcnVuX292ZXIkbGF0IDwtIGFzLm51bWVyaWMoc3RyX21hdGNoKHJ1bl9vdmVyJFdLVCwgIi4qXFwoKC4qKVxccyguKilcXCkiKVssM10pCgpydW5fb3ZlciA8LSBhcnJhbmdlKHJ1bl9vdmVyLCBkZXNjKG4pKQpydW5fb3ZlciA8LSBoZWFkKHJ1bl9vdmVyLCA1KQpydW5fb3ZlciRwb3B1cCA8LSBwYXN0ZSgiPGI+VG9wIDUgaW4gcnVuIG92ZXI8L2I+PGJyPjxicj50b3RhbCBhY2NpZGVudHM6ICIsIHJ1bl9vdmVyJG4sICI8YnI+dmljdGltczogIiwgcnVuX292ZXIkdml0aW1hcywgIjxicj5kZWF0aHM6ICIsIHJ1bl9vdmVyJHZpdGltYXNfbW9ydGUpCgojIGNydXphIGRhZG9zIGRvcyBsb2dyYWRvdXJvcwpsb2dyYWRvdXJvcyA8LSByZWFkLmNzdigiLi9kYWRvcy9sb2dyYWRvdXJvcy5jc3YiKQojIGxldmVscyhsb2dyYWRvdXJvcyRjbGFzc2lmaWNhY2FvKQpsb2dyYWRvdXJvcyA8LSBsb2dyYWRvdXJvcyAlPiUgCiAgZmlsdGVyKGNsYXNzaWZpY2FjYW8gPT0gIlRyYW5zaXRvIFLDoXBpZG8iLCBjb2Rsb2c1ICE9ICJOVUxMIikgJT4lCiAgZ3JvdXBfYnkoY29kbG9nNSkgJT4lCiAgc3VtbWFyaXplKG49bigpKQogIApydW5fb3Zlcl9yYXBpZG8gPC0gZGF0YTIwMTUgJT4lCiAgZmlsdGVyKENPRF9BQ0lEPT00LCBDQURMT0dBICVpbiUgbG9ncmFkb3Vyb3MkY29kbG9nNSkKCiMgZmFjdHBhbCA8LSBjb2xvckZhY3Rvcih0b3BvLmNvbG9ycygxNyksIGRhdGEyMDE1JFRJUE9fQUNJREUsIGFscGhhID0gRkFMU0UsIG9yZGVyZWQgPSBUUlVFKQoKZGF0YTIwMTUgJT4lIGxlYWZsZXQod2lkdGg9ODAwLCBoZWlnaHQ9NTAwLCBwYWRkaW5nPTUpICU+JSBhZGRUaWxlcygpICU+JSAKICBhZGRDaXJjbGVNYXJrZXJzKGRhdGEgPSBkYXRhMjAxNSwgcG9wdXA9fnBvcHVwLCBjbHVzdGVyT3B0aW9ucyA9IG1hcmtlckNsdXN0ZXJPcHRpb25zKCksIGdyb3VwPSJhbGwgYWNjaWRlbnRzIiwgY29sb3I9fmNvbG9yLCByYWRpdXMgPSB+VklUSU1BU19OT1JNICogNCwgd2VpZ2h0ID0gMywgIGZpbGxPcGFjaXR5ID0gflZJVElNQVNfTU9SVEUgKyAwLjIgKSAlPiUKICBhZGRDaXJjbGVNYXJrZXJzKGRhdGEgPSBydW5fb3Zlcl9yYXBpZG8sIHBvcHVwPX5wb3B1cCwgZ3JvdXA9ImF0cm9wZWxhbWVudG9zIG5hcyB2aWFzIGV4cHJlc3NhcyIsIGNvbG9yPX5jb2xvciwgcmFkaXVzID0gOCwgd2VpZ2h0ID0gMywgIGZpbGxPcGFjaXR5ID0gflZJVElNQVNfTU9SVEUgKyAwLjIgKSAlPiUKICBhZGRDaXJjbGVNYXJrZXJzKGRhdGEgPSBkYXRhMjAxNVtkYXRhMjAxNSRDT0RfQUNJRD09NCxdLCBwb3B1cD1+cG9wdXAsIGNsdXN0ZXJPcHRpb25zID0gbWFya2VyQ2x1c3Rlck9wdGlvbnMoKSwgZ3JvdXA9InJ1biBvdmVyIGJ5IHZlaGljbGUiLCBjb2xvcj1+Y29sb3IsIHJhZGl1cyA9IH5WSVRJTUFTX05PUk0gKiA0LCB3ZWlnaHQgPSAzLCBmaWxsT3BhY2l0eSA9IH5WSVRJTUFTX01PUlRFICsgMC4yICkgJT4lCiAgYWRkTWFya2VycyhkYXRhPXRvcDEwLCBncm91cD0id29yc3QgbG9jYXRpb24iLCBwb3B1cD1+cG9wdXApJT4lCiAgYWRkTWFya2VycyhkYXRhPWRlYWRseSwgZ3JvdXA9ImRlYWRseSIsIHBvcHVwPX5wb3B1cCklPiUKICBhZGRNYXJrZXJzKGRhdGE9cnVuX292ZXIsIGdyb3VwPSJydW4gb3ZlciBieSB2ZWhpY2xlIiwgcG9wdXA9fnBvcHVwKSU+JQogIGFkZExheWVyc0NvbnRyb2woCiAgICAgYmFzZUdyb3VwcyA9IGMoImFsbCBhY2NpZGVudHMiLCAicnVuIG92ZXIgYnkgdmVoaWNsZSIsICJhdHJvcGVsYW1lbnRvcyBuYXMgdmlhcyBleHByZXNzYXMiKSwKICAgICAjb3ZlcmxheUdyb3VwcyA9IGMoImFjY2lkZW50IiwgInJ1biBvdmVyIiwgInRvcDEwIiwgImRlYWRseSIpLAogICAgIG92ZXJsYXlHcm91cHMgPSBjKCJ3b3JzdCBsb2NhdGlvbiIsICJkZWFkbHkiKSwKICAgICBvcHRpb25zID0gbGF5ZXJzQ29udHJvbE9wdGlvbnMoY29sbGFwc2VkID0gRkFMU0UpLAogICAgIHBvc2l0aW9uPSJib3R0b21sZWZ0IgogICkKCiMgYWRkUmVjdGFuZ2xlcyhkYXRhPWxvY2F0aW9ucywgbGF0MT1+bGF0MSwgbG5nMT1+bG5nMSwgbGF0Mj1+bGF0MiwgbG5nMj1+bG5nMiwgZ3JvdXA9InRvcDEwIiwgcG9wdXA9fnBvcHVwLCBjb2xvcj0ib3JhbmdlIiklPiUKCiNhZGRDaXJjbGVNYXJrZXJzKHBvcHVwID0gflRJUE9fQUNJREVfREVTQ1IsIGNsdXN0ZXJPcHRpb25zID0gbWFya2VyQ2x1c3Rlck9wdGlvbnMoKSwgY29sb3IgPSB+ZmFjdHBhbChUSVBPX0FDSURFKSwgZ3JvdXAgPSB+Q09EX0FDSUQpICU+JQojYWRkTGF5ZXJzQ29udHJvbCgKICAjICAgIG92ZXJsYXlHcm91cHMgPSBjKDIsIDQpLAogICMgICAgb3B0aW9ucyA9IGxheWVyc0NvbnRyb2xPcHRpb25zKGNvbGxhcHNlZCA9IEZBTFNFKQogICMgKQoKIyBhZGRDaXJjbGVNYXJrZXJzKHBvcHVwID0gflRJUE9fQUNJREVfREVTQ1IsIGNsdXN0ZXJPcHRpb25zID0gbWFya2VyQ2x1c3Rlck9wdGlvbnMoKSwgY29sb3IgPSB+ZmFjdHBhbChUSVBPX0FDSURFKSkgCgojICU+JSBhZGRMZWdlbmQocGFsID0gZmFjdHBhbCwgdmFsdWVzID0gflRJUE9fQUNJREVfREVTQ1IsIG9wYWNpdHkgPSAxLCB0aXRsZSA9ICJUcmFmZmljIEluY2lkZW50cyAtIDIwMTUiKQoKCmBgYAoKClN1bW1hcnk6CgpgYGB7ciwgZXZhbD1GQUxTRSwgZWNobz1GQUxTRX0Kc3VtYXJpbyA8LSBkYXRhMjAxNSAlPiUKICBncm91cF9ieShUSVBPX0FDSURFX0RFU0NSKSAlPiUKICBzdW1tYXJpemUoYWNjaWRlbnRzPW4oKSwgdmljdGltcz1zdW0oVklUSU1BU19OT1JNKSwgZGVhdGhzPXN1bShWSVRJTUFTX01PUlRFKSkgJT4lCiAgYXJyYW5nZShkZXNjKHZpY3RpbXMpKQpgYGAKCi0tLS0KCgojIyBBcHBlbmRpeCBJIC0gU291cmNlIENvZGUKCk1hZGUgd2l0aCBbUl0oaHR0cHM6Ly93d3cucnN0dWRpby5jb20vKSBhbmQgW0xlYWZsZXRdKGh0dHBzOi8vcnN0dWRpby5naXRodWIuaW8vbGVhZmxldC8pLCBzb3VyY2UgY29kZToKCmBgYHtyLCBldmFsPUZBTFNFfQojIGxvYWQgbGlicmFyaWVzCiMgaW5zdGFsbC5wYWNrYWdlcygibGVhZmxldCIpCiMgaW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShsZWFmbGV0KSkKc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkoc3RyaW5ncikpCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KGRwbHlyKSkKCiNsb2FkIGFuZCBjbGVhbgpkYXRhMjAxNSA8LSByZWFkLmNzdigiLi9kYWRvcy8yMDE1L29jb3JyZW5jaWFzLXRyYW5zaXRvLXBtc3AtMjAxNS5jc3YiKQpkYXRhMjAxNSRsbmcgPC0gYXMubnVtZXJpYyhzdHJfbWF0Y2goZGF0YTIwMTUkV0tULCAiLipcXCgoLiopXFxzKC4qKVxcKSIpWywyXSkKZGF0YTIwMTUkbGF0IDwtIGFzLm51bWVyaWMoc3RyX21hdGNoKGRhdGEyMDE1JFdLVCwgIi4qXFwoKC4qKVxccyguKilcXCkiKVssM10pCmRhdGEyMDE1IDwtIGRhdGEyMDE1W2NvbXBsZXRlLmNhc2VzKGRhdGEyMDE1WyxjKCJsYXQiLCJsbmciKV0pLF0KCiMgYWRkIGxlZ2VuZGEgY29tIG8gVElQT19BQ0lERQpkYXRhMjAxNSRUSVBPX0FDSURFX0RFU0NSW2RhdGEyMDE1JFRJUE9fQUNJREU9PSJDTyJdIDwtICJDb2xpc8OjbyIKZGF0YTIwMTUkVElQT19BQ0lERV9ERVNDUltkYXRhMjAxNSRUSVBPX0FDSURFPT0iQ0YiXSA8LSAiQ29saXPDo28gZnJvbnRhbCIKZGF0YTIwMTUkVElQT19BQ0lERV9ERVNDUltkYXRhMjAxNSRUSVBPX0FDSURFPT0iQ1QiXSA8LSAiQ29saXPDo28gdHJhc2VpcmEiCmRhdGEyMDE1JFRJUE9fQUNJREVfREVTQ1JbZGF0YTIwMTUkVElQT19BQ0lERT09IkNMIl0gPC0gIkNvbGlzw6NvIGxhdGVyYWwiCmRhdGEyMDE1JFRJUE9fQUNJREVfREVTQ1JbZGF0YTIwMTUkVElQT19BQ0lERT09IkNWIl0gPC0gIkNvbGlzw6NvIFRyYW5zdmVyc2EiCmRhdGEyMDE1JFRJUE9fQUNJREVfREVTQ1JbZGF0YTIwMTUkVElQT19BQ0lERT09IkNQIl0gPC0gIkNhcG90YW1lbnRvIgpkYXRhMjAxNSRUSVBPX0FDSURFX0RFU0NSW2RhdGEyMDE1JFRJUE9fQUNJREU9PSJUQiJdIDwtICJUb21iYW1lbnRvIgpkYXRhMjAxNSRUSVBPX0FDSURFX0RFU0NSW2RhdGEyMDE1JFRJUE9fQUNJREU9PSJBVCJdIDwtICJBdHJvcGVsYW1lbnRvIgpkYXRhMjAxNSRUSVBPX0FDSURFX0RFU0NSW2RhdGEyMDE1JFRJUE9fQUNJREU9PSJBQSJdIDwtICJBdHJvcGVsYW1lbnRvIGFuaW1hbCIKZGF0YTIwMTUkVElQT19BQ0lERV9ERVNDUltkYXRhMjAxNSRUSVBPX0FDSURFPT0iQ0giXSA8LSAiQ2hvcXVlIgpkYXRhMjAxNSRUSVBPX0FDSURFX0RFU0NSW2RhdGEyMDE1JFRJUE9fQUNJREU9PSJRTSJdIDwtICJRdWVkYSBtb3RvL2JpY2ljbGV0YSIKZGF0YTIwMTUkVElQT19BQ0lERV9ERVNDUltkYXRhMjAxNSRUSVBPX0FDSURFPT0iUVYiXSA8LSAiUXVlZGEgdmXDrWN1bG8iCmRhdGEyMDE1JFRJUE9fQUNJREVfREVTQ1JbZGF0YTIwMTUkVElQT19BQ0lERT09IlFEIl0gPC0gIlF1ZWRhIG9jdXBhbnRlIGRlbnRybyIKZGF0YTIwMTUkVElQT19BQ0lERV9ERVNDUltkYXRhMjAxNSRUSVBPX0FDSURFPT0iUUYiXSA8LSAiUXVlZGEgb2N1cGFudGUgZm9yYSIKZGF0YTIwMTUkVElQT19BQ0lERV9ERVNDUltkYXRhMjAxNSRUSVBPX0FDSURFPT0iT1UiXSA8LSAiT3V0cm9zIgpkYXRhMjAxNSRUSVBPX0FDSURFX0RFU0NSW2RhdGEyMDE1JFRJUE9fQUNJREU9PSJTSSJdIDwtICJTZW0gaW5mb3JtYcOnw6NvIgoKIyBub3JtYWxpemEgbnVtZXJvIGRlIHZpdGltYXMKZGF0YTIwMTUkVklUSU1BU19OT1JNW2RhdGEyMDE1JFZJVElNQVMgPCAxMDBdIDwtIGRhdGEyMDE1W2RhdGEyMDE1JFZJVElNQVMgPCAxMDAsMTddCmRhdGEyMDE1JFZJVElNQVNfTk9STVtkYXRhMjAxNSRWSVRJTUFTID49IDEwMF0gPC0gZGF0YTIwMTVbZGF0YTIwMTUkVklUSU1BUyA+PSAxMDAsMTddICUvJSAxMDAKZGF0YTIwMTUkVklUSU1BU19NT1JURSA8LSAwCmRhdGEyMDE1JFZJVElNQVNfTU9SVEVbZGF0YTIwMTUkVklUSU1BUyA+PSAxMDBdIDwtIGRhdGEyMDE1W2RhdGEyMDE1JFZJVElNQVMgPj0gMTAwLDE3XSAlJSAxMDAKCiMgcG9wdXAKZGF0YTIwMTUkcG9wdXAgPC0gcGFzdGUoZGF0YTIwMTUkVElQT19BQ0lERV9ERVNDUiwgIjxicj48YnI+dml0aW1hcyBmZXJpZGFzOiIsIGRhdGEyMDE1JFZJVElNQVNfTk9STSwgIjxicj52aXRpbWFzIGZhdGFpczoiLCBkYXRhMjAxNSRWSVRJTUFTX01PUlRFLCAiPGJyPmNvZC4gbG9jYWxpemHDp8OjbzogIiwgZGF0YTIwMTUkQ0FETE9HQSk7CgojIGNvbG9yCmRhdGEyMDE1JGNvbG9yW2RhdGEyMDE1JENPRF9BQ0lEPT0yXSA8LSAiYmx1ZSIKZGF0YTIwMTUkY29sb3JbZGF0YTIwMTUkQ09EX0FDSUQ9PTRdIDwtICJyZWQiIAoKIyB0b3AgMTAgbG9jYXRpb25zCmxvY2F0aW9ucyA8LSBkYXRhMjAxNSAlPiUKICBncm91cF9ieShXS1QpICU+JQogIHN1bW1hcml6ZShuPW4oKSwgdml0aW1hcz1zdW0oVklUSU1BU19OT1JNKSwgdml0aW1hc19tb3J0ZT1zdW0oVklUSU1BU19NT1JURSkpCgpsb2NhdGlvbnMkbG5nIDwtIGFzLm51bWVyaWMoc3RyX21hdGNoKGxvY2F0aW9ucyRXS1QsICIuKlxcKCguKilcXHMoLiopXFwpIilbLDJdKQpsb2NhdGlvbnMkbGF0IDwtIGFzLm51bWVyaWMoc3RyX21hdGNoKGxvY2F0aW9ucyRXS1QsICIuKlxcKCguKilcXHMoLiopXFwpIilbLDNdKQoKbG9jYXRpb25zIDwtIGFycmFuZ2UobG9jYXRpb25zLCBkZXNjKG4pKQoKdG9wMTAgPC0gaGVhZChsb2NhdGlvbnMsIDEwKQoKdG9wMTAkcG9wdXAgPC0gcGFzdGUoIjxiPlRPUCAxMCBpbiBudW1iZXIgb2YgYWNjaWRlbnRzPC9iPjxicj48YnI+dG90YWwgYWNjaWRlbnRzOiAiLCB0b3AxMCRuLCAiPGJyPnZpY3RpbXM6ICIsIHRvcDEwJHZpdGltYXMsICI8YnI+ZGVhdGhzOiAiLCB0b3AxMCR2aXRpbWFzX21vcnRlKQoKbG9jYXRpb25zIDwtIGFycmFuZ2UobG9jYXRpb25zLCBkZXNjKHZpdGltYXNfbW9ydGUpKQpkZWFkbHkgPC0gaGVhZChsb2NhdGlvbnMsIDEwKQpkZWFkbHkkcG9wdXAgPC0gcGFzdGUoIjxiPkRlYWRseSBMb2NhdGlvbjwvYj48YnI+PGJyPnRvdGFsIGFjY2lkZW50czogIiwgZGVhZGx5JG4sICI8YnI+dmljdGltczogIiwgZGVhZGx5JHZpdGltYXMsICI8YnI+ZGVhdGhzOiAiLCBkZWFkbHkkdml0aW1hc19tb3J0ZSkKCiMgbW9zdCBydW4gb3ZlcgpydW5fb3ZlciA8LSBkYXRhMjAxNVtkYXRhMjAxNSRDT0RfQUNJRD09NCxdICU+JQogIGdyb3VwX2J5KFdLVCkgJT4lCiAgc3VtbWFyaXplKG49bigpLCB2aXRpbWFzPXN1bShWSVRJTUFTX05PUk0pLCB2aXRpbWFzX21vcnRlPXN1bShWSVRJTUFTX01PUlRFKSkKCnJ1bl9vdmVyJGxuZyA8LSBhcy5udW1lcmljKHN0cl9tYXRjaChydW5fb3ZlciRXS1QsICIuKlxcKCguKilcXHMoLiopXFwpIilbLDJdKQpydW5fb3ZlciRsYXQgPC0gYXMubnVtZXJpYyhzdHJfbWF0Y2gocnVuX292ZXIkV0tULCAiLipcXCgoLiopXFxzKC4qKVxcKSIpWywzXSkKCnJ1bl9vdmVyIDwtIGFycmFuZ2UocnVuX292ZXIsIGRlc2MobikpCnJ1bl9vdmVyIDwtIGhlYWQocnVuX292ZXIsIDUpCnJ1bl9vdmVyJHBvcHVwIDwtIHBhc3RlKCI8Yj5Ub3AgNSBpbiBydW4gb3ZlcjwvYj48YnI+PGJyPnRvdGFsIGFjY2lkZW50czogIiwgcnVuX292ZXIkbiwgIjxicj52aWN0aW1zOiAiLCBydW5fb3ZlciR2aXRpbWFzLCAiPGJyPmRlYXRoczogIiwgcnVuX292ZXIkdml0aW1hc19tb3J0ZSkKCiMgY3J1emEgZGFkb3MgZG9zIGxvZ3JhZG91cm9zCmxvZ3JhZG91cm9zIDwtIHJlYWQuY3N2KCIuL2RhZG9zL2xvZ3JhZG91cm9zLmNzdiIpCiMgbGV2ZWxzKGxvZ3JhZG91cm9zJGNsYXNzaWZpY2FjYW8pCmxvZ3JhZG91cm9zIDwtIGxvZ3JhZG91cm9zICU+JSAKICBmaWx0ZXIoY2xhc3NpZmljYWNhbyA9PSAiVHJhbnNpdG8gUsOhcGlkbyIsIGNvZGxvZzUgIT0gIk5VTEwiKSAlPiUKICBncm91cF9ieShjb2Rsb2c1KSAlPiUKICBzdW1tYXJpemUobj1uKCkpCiAgCnJ1bl9vdmVyX3JhcGlkbyA8LSBkYXRhMjAxNSAlPiUKICBmaWx0ZXIoQ09EX0FDSUQ9PTQsIENBRExPR0EgJWluJSBsb2dyYWRvdXJvcyRjb2Rsb2c1KQoKIyBmYWN0cGFsIDwtIGNvbG9yRmFjdG9yKHRvcG8uY29sb3JzKDE3KSwgZGF0YTIwMTUkVElQT19BQ0lERSwgYWxwaGEgPSBGQUxTRSwgb3JkZXJlZCA9IFRSVUUpCgpkYXRhMjAxNSAlPiUgbGVhZmxldCh3aWR0aD04MDAsIGhlaWdodD01MDAsIHBhZGRpbmc9NSkgJT4lIGFkZFRpbGVzKCkgJT4lIAogIGFkZENpcmNsZU1hcmtlcnMoZGF0YSA9IGRhdGEyMDE1LCBwb3B1cD1+cG9wdXAsIGNsdXN0ZXJPcHRpb25zID0gbWFya2VyQ2x1c3Rlck9wdGlvbnMoKSwgZ3JvdXA9ImFsbCBhY2NpZGVudHMiLCBjb2xvcj1+Y29sb3IsIHJhZGl1cyA9IH5WSVRJTUFTX05PUk0gKiA0LCB3ZWlnaHQgPSAzLCAgZmlsbE9wYWNpdHkgPSB+VklUSU1BU19NT1JURSArIDAuMiApICU+JQogIGFkZENpcmNsZU1hcmtlcnMoZGF0YSA9IHJ1bl9vdmVyX3JhcGlkbywgcG9wdXA9fnBvcHVwLCBncm91cD0iYXRyb3BlbGFtZW50b3MgbmFzIHZpYXMgZXhwcmVzc2FzIiwgY29sb3I9fmNvbG9yLCByYWRpdXMgPSA4LCB3ZWlnaHQgPSAzLCAgZmlsbE9wYWNpdHkgPSB+VklUSU1BU19NT1JURSArIDAuMiApICU+JQogIGFkZENpcmNsZU1hcmtlcnMoZGF0YSA9IGRhdGEyMDE1W2RhdGEyMDE1JENPRF9BQ0lEPT00LF0sIHBvcHVwPX5wb3B1cCwgY2x1c3Rlck9wdGlvbnMgPSBtYXJrZXJDbHVzdGVyT3B0aW9ucygpLCBncm91cD0ic29tZW50ZSBhdHJvcGVsYW1lbnRvcyIsIGNvbG9yPX5jb2xvciwgcmFkaXVzID0gflZJVElNQVNfTk9STSAqIDQsIHdlaWdodCA9IDMsIGZpbGxPcGFjaXR5ID0gflZJVElNQVNfTU9SVEUgKyAwLjIgKSAlPiUKICBhZGRNYXJrZXJzKGRhdGE9dG9wMTAsIGdyb3VwPSJ3b3JzdCBsb2NhdGlvbiIsIHBvcHVwPX5wb3B1cCklPiUKICBhZGRNYXJrZXJzKGRhdGE9ZGVhZGx5LCBncm91cD0iZGVhZGx5IiwgcG9wdXA9fnBvcHVwKSU+JQogIGFkZE1hcmtlcnMoZGF0YT1ydW5fb3ZlciwgZ3JvdXA9InNvbWVudGUgYXRyb3BlbGFtZW50b3MiLCBwb3B1cD1+cG9wdXApJT4lCiAgYWRkTGF5ZXJzQ29udHJvbCgKICAgICBiYXNlR3JvdXBzID0gYygiYWxsIGFjY2lkZW50cyIsICJzb21lbnRlIGF0cm9wZWxhbWVudG9zIiwgImF0cm9wZWxhbWVudG9zIG5hcyB2aWFzIGV4cHJlc3NhcyIpLAogICAgIG92ZXJsYXlHcm91cHMgPSBjKCJ3b3JzdCBsb2NhdGlvbiIsICJkZWFkbHkiKSwKICAgICBvcHRpb25zID0gbGF5ZXJzQ29udHJvbE9wdGlvbnMoY29sbGFwc2VkID0gRkFMU0UpLAogICAgIHBvc2l0aW9uPSJib3R0b21sZWZ0IgogICkKYGBg